home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / a86v400.zip / A11.DOC < prev    next >
Text File  |  1994-12-21  |  31KB  |  824 lines

  1. CHAPTER 11   MACROS AND CONDITIONAL ASSEMBLY
  2.  
  3.  
  4. Macro Facility
  5.  
  6. A86 contains an easy-to-use, but very powerful macro facility.
  7. The facility subsumes the capabilities of most assemblers,
  8. including operand concatenation, repeat, indefinite repeat (often
  9. called IRP), indefinite repeat character (IRPC), passing macro
  10. operands by text or by value, comparing macro operands to
  11. strings, and detecting blank macro operands.  Unlike other
  12. assemblers, A86 integrates these functions into the main macro
  13. facility; so they can be invoked without clumsy syntax, or
  14. strange characters in the macro-call operands.
  15.  
  16.  
  17. Simple Macro Syntax
  18.  
  19. All macros must be defined before they are used.  A macro
  20. definition consists of the name of the macro, followed by the
  21. word MACRO, followed by the text of the macro, followed by #EM,
  22. which marks the end of the macro.
  23.  
  24. Many assembly languages require a list of dummy operand names to
  25. follow the word MACRO.  A86 does not: the operands are denoted in
  26. the text with the fixed names #1, #2, #3, ... up to a limit of
  27. #9, for each operand in order.  If there is anything following
  28. the word MACRO, it is considered part of the macro text.
  29.  
  30. Examples:
  31.  
  32. ; CLEAR sets the register operand to zero.
  33.  
  34. CLEAR  MACRO  SUB #1,#1 #EM
  35.  
  36.   CLEAR AX      ; generates a SUB AX,AX instruction
  37.   CLEAR BX      ; generates a SUB BX,BX instruction
  38.  
  39.  
  40. ; MOVM moves the second operand to the first operand.
  41. ;   Both operands can be memory variables.
  42.  
  43. MOVM  MACRO
  44.   MOV AL,#2
  45.   MOV #1,AL
  46. #EM
  47.  
  48. VAR1  DB  ?
  49. VAR2  DB  ?
  50.  
  51. MOVM VAR1,VAR2  ; generates MOV AL,VAR2 followed by MOV VAR1,AL
  52.                                                              11-2
  53.  
  54. Formatting in Macro Definitions and Calls
  55.  
  56. The format of a macro definition is flexible.  If the macro text
  57. consists of a single instruction, the definition can be given in
  58. a single line, as in the CLEAR macro given above.  There is no
  59. particular advantage to doing this, however: A86 prunes all
  60. unnecessary spaces, blank lines, and comments from the macro text
  61. before entering the text into the symbol table.  I recommend the
  62. more spread-out format of the MOVM macro, for program
  63. readability.
  64.  
  65. All special macro operators within a macro definition begin with
  66. a hash sign # (a hex 23 byte).  The letters following the hash
  67. sign can be given in either upper case or lower case.  Hash-sign
  68. operators are recognized even within quoted strings.  If you wish
  69. the hash sign to be treated literally, and not as the start of a
  70. special macro operator, you must give 2 consecutive hash signs:
  71. ##.  For example:
  72.  
  73. FOO MACRO
  74.   DB '##1'
  75.   DB '#1'
  76. #em
  77.  
  78. FOO abc      ; produces  DB '#1'  followed by  DB 'abc'
  79.  
  80. The format of the macro call line is also flexible.  A macro call
  81. consists of the name of the macro, followed by the operands to be
  82. plugged into the macro.  A86 prunes leading and trailing blanks
  83. from the operands of a macro call.  The operands to a macro call
  84. are always separated by commas.  Also, as in all A86 source
  85. lines, a semi-colon occurring outside of a quoted string is the
  86. start of a comment, ignored by A86.  If you want to include
  87. commas, blanks, or semi-colons in your operands, you must enclose
  88. your operand in single quotes.
  89.  
  90.  
  91.  
  92. Macro Operand Substitution
  93.  
  94. Some macro assemblers expect the operands to macro calls to
  95. follow the same syntax as the operands to instructions.  In those
  96. assemblers, the operands are parsed, and reduced to numeric
  97. values before being plugged into the macro definition text.  This
  98. is called "passing by value".  As its default, A86 does not pass
  99. by value, it passes by text.  The only parsing of operands done
  100. by the macro processor is to determine the start and the finish
  101. of the operand text.  That text is substituted, without regard
  102. for its contents, for the "#n" that appears in the macro
  103. definition.  The text is interpreted by A86 only after a complete
  104. line is expanded and as it is assembled.
  105.                                                              11-3
  106.  
  107. If the first non-blank character after the macro name is a comma,
  108. then the first operand is null: any occurrences of #1 in the
  109. macro text will be deleted, and replaced with nothing.  Likewise,
  110. any two consecutive commas with no non-blanks between them will
  111. result in the corresponding null operand.  Also, out-of-range
  112. operands are null; for example, #3 is a null operand if only two
  113. operands are provided in the call.
  114.  
  115. Null operands to macros are not in themselves illegal.  They will
  116. produce errors only if the resulting macro expansion is illegal.
  117.  
  118. The method of passing by text allows operand text to be plugged
  119. anywhere into a macro, even within symbol names.  For example:
  120.  
  121. ; KF_ENTRY creates an entry in the KFUNCS table, consisting of a
  122. ;   pointer to a KF_ action routine.  It also declares the
  123. ;   corresponding CF_ symbol, which is the index within the table
  124. ;   for that entry.
  125.  
  126. KF_ENTRY  MACRO
  127.   CF_#1  EQU  ($-KFUNCS)/2+080
  128.   DW  KF_#1
  129. #EM
  130.  
  131. KFUNCS:
  132.   KF_ENTRY  UP
  133.   KF_ENTRY  DOWN
  134.  
  135. ; The above code is equivalent to:
  136. ;
  137. ;  KFUNCS:
  138. ;    DW KF_UP
  139. ;    DW KF_DOWN
  140. ;
  141. ;  CF_UP    EQU  080
  142. ;  CF_DOWN  EQU  081
  143.  
  144.  
  145.  
  146. Quoted String Operands
  147.  
  148. As mentioned before, if you want to include blanks, commas, or
  149. semicolons in your operands, you enclose the operand in single
  150. quotes.  In the vast majority of cases in which these special
  151. characters need to be part of operands, the user wants them to be
  152. quoted in the final, assembled line also.  Therefore, the quotes
  153. are passed in the operand.  To override this, and strip the
  154. quotes from the string, you precede the quoted string with a hash
  155. sign.  Examples:
  156.                                                              11-4
  157.  
  158. DBW  MACRO
  159.   DB  #1
  160.   DW  #2
  161. #EM
  162.  
  163. DBW  'E', E_POINTER
  164. DBW  'W', W_POINTER
  165.  
  166. ; note that if quotes were not passed, the above lines would have
  167. ;   to be   DBW  '''E''', E_POINTER;    DBW  '''W''', W_POINTER
  168.  
  169. FETCH_CHAR  MACRO
  170.   LODSB
  171.   #1
  172.   CALL PROCESS_CHAR
  173. #EM
  174.  
  175. FETCH_CHAR  STOSB      ; generates STOSB as second instruction
  176. FETCH_CHAR  #'INC DI'  ; generates INC DI as second instruction
  177.  
  178.  
  179.  
  180. Looping by Operands in Macros
  181.  
  182. A86's macro facility contains two kinds of loops: you can loop
  183. once for each operand in a range of operands; or you can loop
  184. once for each character within an operand.  The first kind of
  185. loop, the R-loop, is discussed in this section; the second kind,
  186. the C-loop, is discussed later.
  187.  
  188. An R-loop is a stretch of macro-definition code that is repeated
  189. when the macro is expanded.  In addition to the fixed operands #1
  190. through #9, you can specify a variable operand, whose number
  191. changes each time through the loop.  You give the variable
  192. operand one of the 4 names #W, #X, #Y, or #Z.
  193.  
  194. An R-loop begins with #R, followed immediately by the letter
  195. W,X,Y, or Z naming the variable, followed by the number of the
  196. first operand to be used, followed by the number of the last
  197. operand to be used.  After the #Rxnn is the text to be repeated.
  198. The R-loop ends with #ER.  For example:
  199.  
  200. STORE3 MACRO
  201.   MOV AX,#1
  202. #RY24               ; "repeat for Y running from 2 through 4"
  203.   MOV #Y,AX
  204. #ER
  205. #EM
  206.  
  207. STORE3  VAR1,VAR2,VAR3,VAR4
  208.  
  209. ; the above call produces the 4 instructions MOV AX,VAR1; MOV VAR2,AX;
  210. ;   MOV VAR3,AX; MOV VAR4,AX.
  211.                                                              11-5
  212.  
  213. The #L Last Operator and Indefinite Repeats
  214.  
  215. A86 recognizes the special operator #L, which is the last operand
  216. in a macro call.  #L can appear anywhere in macro text; but its
  217. big power occurs in conjunction with R-loops, to yield an
  218. indefinite-repeat facility.
  219.  
  220. A common example is as follows: you can take any macro that is
  221. designed for one operand, and easily convert it into a macro that
  222. accepts any number of operands.  You do this by placing the
  223. command #RX1L, "repeat for X running from 1 through L", at the
  224. start of the macro, and the command #ER at the end just before
  225. the #EM.  Finally, you replace all instances of #1 in the macro
  226. with #X.  We see how this works with the CLEAR macro:
  227.  
  228. CLEAR MACRO #RX1L
  229.   SUB #X,#X
  230. #ER
  231. #EM